﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using System.Data.Objects;
using DotNetOpenAuth.AspNet;
using Microsoft.Web.WebPages.OAuth;
using WebMatrix.WebData;
using SWGeneracionE.Filters;
using SWGeneracionE.Models;
using SWGeneracionE.Libraries;
using System.Data.Objects.SqlClient;

namespace SWGeneracionE.Controllers
{
    // probar todo el funcionamiento
    public class ParticipanteController : BaseController
    {

        //
        // GET: /Participante/Personas

        [Authorize]
        public ActionResult Personas()
        {
            ViewBag.listTipoTransporte = GetTipoTransporte();

            return View();
        }

        //
        // GET: /Participante/CancelInscripcion

        [Authorize]
        public ActionResult CancelInscripcion()
        {
            ViewBag.listTipoTransporte = GetTipoTransporte();

            return View();
        }

        //
        // GET: /Participante/Participantes

        public ActionResult Participantes()
        {
            ViewBag.listTipoTransporte = GetTipoTransporte();

            return View();
        }

        //
        // GET: /Participante/Checkin

        [Authorize]
        public ActionResult Checkin()
        {
            ViewBag.listTipoTransporte = GetTipoTransporte();

            return View();
        }

        #region "Acciones Personas"
        [HttpPost]
        public JsonResult PersonList(string nombres, string apellidos, string edad, string sexo, string estadocivil,
                                     string pais, string iglesia, string documentoID, string estado, string codigo, 
                                     string tipotransporte, string pagobus, string datosauto, string duenioauto, string contrato,
                                     string recaudacion, string cortesia, string abonomin, string abonomax, string tutor,
                                     string carta, string firmas, string inscrito, string checkin, int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = null)
        {
            try
            {
                //validar los 22 filtros
                int idEvento = int.Parse(ViewBag.Evento);
                if (string.IsNullOrEmpty(jtSorting))
                    jtSorting = "nombres ASC";
                var query = PersonListByFilter(nombres,apellidos,edad,sexo,estadocivil,pais,iglesia,documentoID,estado,codigo,
                                               tipotransporte, pagobus, datosauto, duenioauto, contrato, recaudacion, cortesia,
                                               abonomin, abonomax, tutor, carta, firmas, checkin, idEvento, inscrito)
                             .Select(p => new { pte = p, pteEvento = p.ParticipanteXEvento.FirstOrDefault(i => i.idEvento == idEvento) } )
                             .Select(p => new
                              {
                                idParticipante = p.pte.idParticipante, nombres = p.pte.nombres, apellidos = p.pte.apellidos, 
                                fechaNacimiento = p.pte.fechaNacimiento, sexo = p.pte.sexo, estadoCivil = p.pte.estadoCivil, 
                                telefonoCasa = p.pte.telefonoCasa, telefonoMovil = p.pte.telefonoMovil, telefonoTrabajo = p.pte.telefonoTrabajo,
                                correoElectronico = p.pte.correoElectronico, direccionCasa = p.pte.direccionCasa, direccionTrabajo = p.pte.direccionTrabajo,
                                idPais = p.pte.idPais, idIglesia = p.pte.idIglesia,
                                edad = DateTime.Now.Year - p.pte.fechaNacimiento.Year +
                                        (DateTime.Now < EntityFunctions.AddYears(p.pte.fechaNacimiento, DateTime.Now.Year - p.pte.fechaNacimiento.Year) ? -1 : 0),
                                tieneDocs = p.pte.DocumentoXParticipante.Count() > 0 ? Constantes.RESPUESTA_POSITIVA : Constantes.RESPUESTA_NEGATIVA,
                                inscrito = p.pteEvento != null ? p.pteEvento.estado == Constantes.ESTADOPARTICIPANTE_INSCRITO || p.pteEvento.estado == Constantes.ESTADOPARTICIPANTE_CANCELADO
                                            ? true : false : false,
                                codigo = p.pteEvento != null ? p.pteEvento.codigo
                                            : string.Empty,
                                estado = (short?)p.pteEvento.estado,
                                fechaInscripcion = (DateTime?)p.pteEvento.fechaInscripcion,
                                habitacionge = p.pteEvento.AsignacionGrupo.Count > 0 ? 
                                               SqlFunctions.StringConvert((double)p.pteEvento.AsignacionGrupo.FirstOrDefault().Grupo.idGrupo) : "",
                                habitacionhotel = p.pteEvento.AsignacionGrupo.Count > 0 ? 
                                                  ((p.pteEvento.AsignacionGrupo.FirstOrDefault().Grupo.Edificio != null ? p.pteEvento.AsignacionGrupo.FirstOrDefault().Grupo.Edificio : "")
                                                  + "-" +
                                                  (SqlFunctions.StringConvert((double)p.pteEvento.AsignacionGrupo.FirstOrDefault().Grupo.NoHabitacion)))
                                                  : ""
                              });
                var queryP = query.OrderAndPaging(jtStartIndex, jtPageSize, jtSorting);
                
                //Ordenar por el valor indicado y Paginear
                var persons = queryP.ToList();
                var personsCount = query.Count();

                return Json(new { Result = "OK", Records = persons, TotalRecordCount = personsCount });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error PersonList: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al obtener listado de participantes." });
            }
        }

        public ExcelResult PersonExportExcel(string nombres, string apellidos, string edad, string sexo, string estadocivil,
                                     string pais, string iglesia, string documentoID, string estado, string codigo,
                                     string tipotransporte, string pagobus, string datosauto, string duenioauto, string contrato,
                                     string recaudacion, string cortesia, string abonomin, string abonomax, string tutor,
                                     string carta, string firmas, string inscrito, string checkin)
        {
            try
            {
                //validar los 22 filtros
                int idEvento = int.Parse(ViewBag.Evento);
                var consulta = PersonListByFilter(nombres, apellidos, edad, sexo, estadocivil, pais, iglesia, documentoID, estado, codigo,
                                               tipotransporte, pagobus, datosauto, duenioauto, contrato, recaudacion, cortesia,
                                               abonomin, abonomax, tutor, carta, firmas, checkin, idEvento, inscrito).ToList();

                var contador = consulta.Count;
                //se crea el objeto con los encabezados y datos que iran en la hoja de excel
                var excelData = new ExcelData();
                excelData.headers = new string[38];
                excelData.contents = new string[contador, 38];
                excelData.headers[0] = "Nombre";                    
                excelData.headers[1] = "Fecha Nacimiento";
                excelData.headers[2] = "Edad";                      
                excelData.headers[3] = "Género";
                excelData.headers[4] = "Estado Civil";              
                excelData.headers[5] = "Tel. Casa";
                excelData.headers[6] = "Celular";                   
                excelData.headers[7] = "Tel. Trabajo";
                excelData.headers[8] = "E-mail";                    
                excelData.headers[9] = "Dirección Casa";
                excelData.headers[10] = "Dirección Trabajo";        
                excelData.headers[11] = "Pais";
                excelData.headers[12] = "Iglesia";
                excelData.headers[13] = "Documento ID";
                excelData.headers[14] = "Estado";                   
                excelData.headers[15] = "Fecha Inscripción";
                excelData.headers[16] = "Código";
                excelData.headers[17] = "Checkin";    
                excelData.headers[18] = "Tipo Transporte";
                excelData.headers[19] = "Marca Vehículo";           
                excelData.headers[20] = "Placa Vehículo";
                excelData.headers[21] = "Color Vehículo";           
                excelData.headers[22] = "Dueño Vehículo";
                excelData.headers[23] = "Firmó Contrato";           
                excelData.headers[24] = "Recaudación";
                excelData.headers[25] = "Cortesía";                 
                excelData.headers[26] = "Tutor";
                excelData.headers[27] = "Carta";                    
                excelData.headers[28] = "Firma Padre";
                excelData.headers[29] = "Firma Madre";              
                excelData.headers[30] = "Pago Bus";
                excelData.headers[31] = "Abono GTQ";                
                excelData.headers[32] = "Abono USD";
                excelData.headers[33] = "Recaudado GTQ";                
                excelData.headers[34] = "Total Abono Aprox. (GTQ)";
                excelData.headers[35] = "Observaciones";
                excelData.headers[36] = "Hab. GE";
                excelData.headers[37] = "Hab. Hotel";

                var i = 0;
                //se llenan los datos según los obtenidos en la consulta
                foreach (var participante in consulta)
                {
                    //datos personales, tomar en cuenta valores Nullable
                    var edadParticipante = Constantes.EdadParticipante(participante.fechaNacimiento);
                    excelData.contents[i, 0] = participante.apellidos + ", " + participante.nombres;
                    excelData.contents[i, 1] = String.Format("{0:" + Constantes.FORMATO_FECHA + "}", participante.fechaNacimiento);
                    excelData.contents[i, 2] = edadParticipante.ToString();                  
                    excelData.contents[i, 3] = participante.sexo;
                    excelData.contents[i, 4] = Constantes.EstadoCivil(participante.estadoCivil);          
                    excelData.contents[i, 5] = participante.telefonoCasa != null ? participante.telefonoCasa : string.Empty;
                    excelData.contents[i, 6] = participante.telefonoMovil;
                    excelData.contents[i, 7] = participante.telefonoTrabajo != null ? participante.telefonoTrabajo : string.Empty;
                    excelData.contents[i, 8] = participante.correoElectronico;
                    excelData.contents[i, 9] = participante.direccionCasa != null ? participante.direccionCasa : string.Empty;
                    excelData.contents[i, 10] = participante.direccionTrabajo != null ? participante.direccionTrabajo : string.Empty;
                    excelData.contents[i, 11] = participante.Pais.nombre;
                    excelData.contents[i, 12] = participante.Iglesia.nombre;
                    excelData.contents[i, 13] = participante.DocumentoXParticipante.Count > 0 ? participante.DocumentoXParticipante.FirstOrDefault().noDocumento : string.Empty;

                    //datos relacionados con el evento, si se ha inscrito
                    ParticipanteXEvento participanteEvento = ParticipanteEvento(participante.ParticipanteXEvento);
                    if (participanteEvento != null)
                    {
                        excelData.contents[i, 14] = Constantes.EstadoParticipante(participanteEvento.estado);
                        if (participanteEvento.estado == Constantes.ESTADOPARTICIPANTE_INSCRITO || participanteEvento.estado == Constantes.ESTADOPARTICIPANTE_CANCELADO)
                        {
                            excelData.contents[i, 15] = String.Format("{0:" + Constantes.FORMATO_FECHA + "}", participanteEvento.fechaInscripcion);
                            excelData.contents[i, 16] = participanteEvento.codigo;
                            excelData.contents[i, 17] = participanteEvento.checkin != null ? (bool)participanteEvento.checkin ? Constantes.RESPUESTA_POSITIVA : Constantes.RESPUESTA_NEGATIVA : Constantes.RESPUESTA_NEGATIVA;
                            //validar si ya proporcionó datos de transporte
                            if (participanteEvento.tipoTransporte != null)
                            {
                                excelData.contents[i, 18] = Constantes.TipoTransporte((short)participanteEvento.tipoTransporte);
                                // si es bus entonces validar que ya ha pagado
                                if (participanteEvento.tipoTransporte == Constantes.TIPOTRANSPORTE_BUS){
                                    excelData.contents[i, 30] = participanteEvento.ValidarPagoBus ? Constantes.RESPUESTA_POSITIVA : Constantes.RESPUESTA_NEGATIVA;
                                }else
                                {
                                    // si es automóvil, obtener datos del auto
                                    excelData.contents[i, 19] = participanteEvento.marcaVehiculo != null ? participanteEvento.marcaVehiculo : string.Empty;
                                    excelData.contents[i, 20] = participanteEvento.placaVehiculo != null ? participanteEvento.placaVehiculo : string.Empty;
                                    excelData.contents[i, 21] = participanteEvento.colorVehiculo != null ? participanteEvento.colorVehiculo : string.Empty;
                                    //si es dueño del vehículo, respuesta SI/NO
                                    excelData.contents[i, 22] = participanteEvento.duenioVehiculo != null 
                                        ? (bool)participanteEvento.duenioVehiculo ? Constantes.RESPUESTA_POSITIVA : Constantes.RESPUESTA_NEGATIVA 
                                        : string.Empty;
                                }
                            }
                            //validar si es menor
                            if (edadParticipante < Constantes.MAYORIA_EDAD)
                            {
                                excelData.contents[i, 26] = participanteEvento.Tutor != null
                                    ? participanteEvento.Tutor.codigo 
                                    : string.Empty;
                                //si tiene carta, firma de padre y firma de madre (respuesta SI/NO)
                                excelData.contents[i, 27] = participanteEvento.cartaTutor != null
                                        ? (bool)participanteEvento.cartaTutor ? Constantes.RESPUESTA_POSITIVA : Constantes.RESPUESTA_NEGATIVA
                                        : string.Empty;
                                excelData.contents[i, 28] = participanteEvento.firmaPadre != null
                                        ? (bool)participanteEvento.firmaPadre ? Constantes.RESPUESTA_POSITIVA : Constantes.RESPUESTA_NEGATIVA
                                        : string.Empty;
                                excelData.contents[i, 29] = participanteEvento.firmaMadre != null
                                        ? (bool)participanteEvento.firmaMadre ? Constantes.RESPUESTA_POSITIVA : Constantes.RESPUESTA_NEGATIVA
                                        : string.Empty;
                            }
                            //validar si ya tiene asignada habitación
                            if (participanteEvento.AsignacionGrupo.Count > 0)
                            {
                                Grupo grupo = participanteEvento.AsignacionGrupo.First().Grupo;
                                excelData.contents[i, 36] = grupo.idGrupo.ToString();
                                excelData.contents[i, 37] = (grupo.Edificio !=null ? grupo.Edificio : "") + "-" +
                                    (grupo.NoHabitacion != null ? grupo.NoHabitacion.ToString() : "");
                            }

                            //obtener datos de contrato, recaudación y cortesía (respuesta SI/NO)
                            excelData.contents[i, 23] = participanteEvento.contrato ? Constantes.RESPUESTA_POSITIVA : Constantes.RESPUESTA_NEGATIVA;
                            excelData.contents[i, 24] = participanteEvento.recaudacionS ? Constantes.RESPUESTA_POSITIVA : Constantes.RESPUESTA_NEGATIVA;
                            excelData.contents[i, 25] = participanteEvento.cortesia ? Constantes.RESPUESTA_POSITIVA : Constantes.RESPUESTA_NEGATIVA;
                            excelData.contents[i, 35] = participanteEvento.observaciones != null ? participanteEvento.observaciones : string.Empty;
                            //obtener montos de abonos
                            var abonoLOC = participanteEvento.AbonoTotalLOC;
                            excelData.contents[i, 31] = abonoLOC.ToString(Constantes.SPECIFIER_N);
                            var abonoUSD = participanteEvento.AbonoTotalUSD;
                            excelData.contents[i, 32] = abonoUSD.ToString(Constantes.SPECIFIER_N);
                            var recaudado = participanteEvento.RecaudacionTotal;
                            excelData.contents[i, 33] = recaudado.ToString(Constantes.SPECIFIER_N);
                            var totalAbono = abonoLOC + (abonoUSD * Constantes.TASA_APROX) + recaudado;
                            excelData.contents[i, 34] = totalAbono.ToString(Constantes.SPECIFIER_N);
                        }
                    }
                    else
                    {
                        // no se ha inscrito al evento
                        excelData.contents[i, 14] = "No Inscrito";
                    }

                    i++;
                }

                //Devolver vista parcial
                return new ExcelResult("BaseRetiroGE.xls", PartialView("_ExcelTemplate", excelData));
                
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error PersonExportExcel: " + ex.Message + "--" + ex.Source);
                return null;
            }
        }

        [HttpPost]
        public JsonResult CreatePerson(Participante participante)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    AgregarBitacora("Error CreatePerson: Formulario inválido");
                    return Json(new
                    {
                        Result = "ERROR",
                        Message = "¡El formulario no es válido! " +
                        "Corrija e intente nuevemente."
                    });
                }

                var addedPerson = UoW.participanteRepository.Add(participante);
                UoW.Save();
                AgregarBitacora("Creación de participante (CreatePerson): " + addedPerson.idParticipante.ToString());
                return Json(new { Result = "OK", Record = addedPerson });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error CreatePerson: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al crear participante." });
            }
        }

        [HttpPost]
        public JsonResult UpdatePerson(Participante participante)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    AgregarBitacora("Error UpdatePerson: Formulario inválido");
                    return Json(new
                    {
                        Result = "ERROR",
                        Message = "¡El formulario no es válido! " +
                        "Corrija e intente nuevemente."
                    });
                }

                UoW.participanteRepository.Edit(participante);
                UoW.Save();
                AgregarBitacora("Actualización de participante (UpdatePerson): " + participante.idParticipante.ToString());
                return Json(new { Result = "OK" });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error UpdatePerson: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al actualizar participante." });
            }
        }

        [HttpPost]
        public JsonResult DeletePerson(int idParticipante)
        {
            try
            {
                Participante person = UoW.participanteRepository.FindFirst(p => p.idParticipante == idParticipante);
                UoW.participanteRepository.Delete(person);
                UoW.Save();
                AgregarBitacora("Eliminación de participante (DeletePerson): " + idParticipante.ToString());
                return Json(new { Result = "OK" });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error DeletePerson: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al eliminar participante." });
            }
        }

        [HttpPost]
        public JsonResult GetSexoOptions()
        {
            try
            {
                var generos = UoW.sexoRepository.GetAll().Select(
                                g => new { DisplayText = g.nombre, Value = g.idSexo });
                return Json(new { Result = "OK", Options = generos });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error GetSexoOptions: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al obtener listado de géneros." });
            }
        }

        [HttpPost]
        public JsonResult GetEstadoCivilOptions()
        {
            try
            {
                var estados = UoW.estadoCivilRepository.GetAll().Select(
                                e => new { DisplayText = e.nombre, Value = e.idEstadoCivil });
                return Json(new { Result = "OK", Options = estados });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error GetEstadoCivilOptions: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al obtener listado de estados civiles" });
            }
        }

        [HttpPost]
        public JsonResult InscribirPerson(ParticipanteXEvento participante, String codTutor, bool actualizar)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    AgregarBitacora("Error InscribirPerson: Formulario inválido");
                    return Json(new
                    {
                        Result = "ERROR",
                        Message = "¡El formulario no es válido! <br/>" +
                        "Corrija e intente nuevemente."
                    });
                }

                //colocar datos default (fecha, estado) y datos del tutor según código indicado
                participante.fechaInscripcion = DateTime.Now;
                participante.estado = Constantes.ESTADOPARTICIPANTE_INSCRITO;
                participante.checkin = false;
                if (codTutor != null)
                {
                    ParticipanteXEvento tutor = UoW.participanteXEventoRepository
                        .FindFirst(t => t.codigo == codTutor.Trim() && t.estado == Constantes.ESTADOPARTICIPANTE_INSCRITO);
                    if (tutor != null)
                        participante.idTutor = tutor.idParticipanteXEvento;
                    else
                    {
                        return Json(new
                        {
                            Result = "ERROR",
                            Message = "¡El tutor que ha ingresado es inv&aacute;lido! <br/>" +
                                      "Corrija e intente nuevemente."
                        });
                    }
                }
                //ver si no está para solo marcarle la casilla y actualizar los datos
                ParticipanteXEvento participanteA = UoW.participanteXEventoRepository
                        .FindFirst(p => p.idEvento == participante.idEvento 
                                        && p.idParticipante == participante.idParticipante);
                if (participanteA == null)
                {
                    //insertar, para ello necesitamos los datos del pais (abreviatura y idPais) y la longitud del codigo
                    Participante datosPersonales = UoW.participanteRepository
                        .FindFirst(p => p.idParticipante == participante.idParticipante);
                    string abvPais = datosPersonales.Pais.abreviacion;
                    int padCodigo = int.Parse(GetValorParametro(c_parametro_longitudcodigo));

                    var addedParticipante = UoW.participanteXEventoRepository
                        .AddCodigo(participante, datosPersonales.idPais, abvPais, padCodigo);
                    AgregarBitacora("Inscripción de participante (InscribirPerson): " + addedParticipante.idParticipanteXEvento.ToString());
                    return Json(new
                    {
                        Result = "OK",
                        Message = "Participante inscrito exitosamente con código " + addedParticipante.codigo,
                        CodParticipante = addedParticipante.codigo,
                        Estado = addedParticipante.estado,
                        FechaInscripcion = addedParticipante.fechaInscripcion
                    });
                }
                else
                {
                    //actualizar
                    if (participanteA.estado == Constantes.ESTADOPARTICIPANTE_INGRESADO ||
                        participanteA.estado == Constantes.ESTADOPARTICIPANTE_INSCRITO)
                    {
                        CopiarDataParticipante(participante, participanteA, actualizar);
                        UoW.participanteXEventoRepository.Edit(participanteA);
                        UoW.Save();
                        AgregarBitacora("Actualización de participante (InscribirPerson): " + participanteA.idParticipanteXEvento.ToString());
                        var mensaje = "";
                        if(!actualizar) 
                            mensaje = "Participante inscrito exitosamente con código " + participanteA.codigo;
                        else
                            mensaje = "Actualización exitosa de participante con código " + participanteA.codigo;
                        return Json(new
                        {
                            Result = "OK",
                            Message = mensaje,
                            CodParticipante = participanteA.codigo,
                            Estado = participanteA.estado,
                            FechaInscripcion = participanteA.fechaInscripcion
                        });
                    }
                    else
                    {
                        return Json(new { Result = "ERROR", Message = "No se puede modificar al participante porque su inscripción ha sido cancelada." });
                    }
                }
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error InscribirPerson: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al inscribir participante." });
            }
        }

        private List<SelectListItem> GetTipoTransporte()
        {
            List<TipoTransporte> listTipoTransporte;
            List<SelectListItem> listSelectItem = new List<SelectListItem>();

            try
            {
                
                listTipoTransporte = UoW.tipoTransporteRepository.GetAll();
                foreach (TipoTransporte tt in listTipoTransporte)
                {
                    listSelectItem.Add(new SelectListItem { Text = tt.nombre, Value = tt.idTipoTransporte });
                }
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error GetTipoTransporte: " + ex.Message + "--" + ex.Source);
            }

            return listSelectItem;
        }

        [HttpPost]
        public JsonResult GetPerson(int idParticipante)
        {
            try
            {
                int idEvento = int.Parse(ViewBag.Evento);
                var lp = UoW.participanteRepository.FindFirst(x => x.idParticipante == idParticipante);
                if (lp != null)
                {
                    var participante = new
                    {
                        nombre = lp.nombres + " " + lp.apellidos,
                        fechanacimiento = lp.fechaNacimiento.ToString(Constantes.FORMATO_FECHA),
                        sexo = lp.sexo,
                        estadocivil = Constantes.EstadoCivil(lp.estadoCivil),
                        pais = lp.Pais.nombre,
                        iglesia = lp.Iglesia.nombre,
                        telefonocasa = lp.telefonoCasa != null ? lp.telefonoCasa : string.Empty,
                        telefonomovil = lp.telefonoMovil,
                        telefonotrabajo = lp.telefonoTrabajo != null ? lp.telefonoTrabajo : string.Empty,
                        direccioncasa = lp.direccionCasa != null ? lp.direccionCasa : string.Empty,
                        direcciontrabajo = lp.direccionTrabajo != null ? lp.direccionTrabajo : string.Empty
                    };
                    return Json(new { Result = "OK", Record = participante });
                }
                else
                {
                    return Json(new { Result = "ERROR", Message = "No se encontró participante." });
                }
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error GetPerson: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al obtener participante." });
            }
        }
        #endregion
        
        #region "Acciones Documentos"
        [HttpPost]
        public JsonResult DocIDList(int idParticipante = 0)
        {
            try
            {
                var documentos = UoW.documentoXParticipanteRepository.FindBy(d => d.idParticipante == idParticipante).Select(d => new {
                                    idDocumentoXParticipante = d.idDocumentoXParticipante, idParticipante = d.idParticipante,
                                    idTipoDocumentoID = d.idTipoDocumentoID, noDocumento = d.noDocumento
                                }).ToList();
                var documentosCount = documentos.Count;
                return Json(new { Result = "OK", Records = documentos, TotalRecordCount = documentosCount });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error DocIDList: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al obtener listado de documentos." });
            }
        }

        [HttpPost]
        public JsonResult DeleteDocID(int idDocumentoXParticipante)
        {
            try
            {
                DocumentoXParticipante documento = UoW.documentoXParticipanteRepository.FindFirst(d => d.idDocumentoXParticipante == idDocumentoXParticipante);
                UoW.documentoXParticipanteRepository.Delete(documento);
                UoW.Save();
                AgregarBitacora("Eliminación de documento (DeleteDocID): " + idDocumentoXParticipante.ToString());
                return Json(new { Result = "OK" });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error DeleteDocID: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al eliminar documento." });
            }
        }

        [HttpPost]
        public JsonResult UpdateDocID(DocumentoXParticipante documento)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    AgregarBitacora("Error UpdateDocID: Formulario inválido");
                    return Json(new
                    {
                        Result = "ERROR",
                        Message = "¡El formulario no es válido! " +
                            "Corrija e intente nuevemente."
                    });
                }

                UoW.documentoXParticipanteRepository.Edit(documento);
                UoW.Save();
                AgregarBitacora("Actualización de documento (UpdateDocID): " + documento.idDocumentoXParticipante.ToString());
                return Json(new { Result = "OK" });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error UpdateDocID: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al actualizar documento." });
            }
        }

        [HttpPost]
        public JsonResult CreateDocID(DocumentoXParticipante documento)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    AgregarBitacora("Error CreateDocID: Formulario inválido");
                    return Json(new
                    {
                        Result = "ERROR",
                        Message = "¡El formulario no es válido! " +
                            "Corrija e intente nuevemente."
                    });
                }

                var addedDocumento = UoW.documentoXParticipanteRepository.Add(documento);
                UoW.Save();
                AgregarBitacora("Creación de documento (CreateDocID): " + addedDocumento.idDocumentoXParticipante.ToString());
                return Json(new { Result = "OK", Record = addedDocumento });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error CreateDocID: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al crear documento." });
            }
        }

        [HttpPost]
        public JsonResult GetTipoDocumentoOptions()
        {
            try
            {
                var tiposDocumento = UoW.tipoDocumentoIdRepository.GetAll().Select(
                                t => new { DisplayText = t.nombre, Value = t.idTipoDocumentoID }).OrderBy(t => t.DisplayText).ToList();
                return Json(new { Result = "OK", Options = tiposDocumento });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error GetTipoDocumentoOptions: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al obtener tipos de documento." });
            }
        }
        #endregion

        #region "Acciones Tutor"
        [HttpPost]
        public JsonResult ParticipanteList(string nombres, string apellidos, string codigo, bool bTutor, 
            bool bAsigna, int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = null)
        {
            try
            {
                int idEvento = int.Parse(ViewBag.Evento);
                nombres = nombres.Trim();
                apellidos = apellidos.Trim();
                codigo = codigo.Trim();
                if (string.IsNullOrEmpty(jtSorting))
                    jtSorting = "nombres ASC";
                var query = UoW.participanteXEventoRepository
                    .FindBy(p => (p.idEvento == idEvento) &&
                     (p.estado == Constantes.ESTADOPARTICIPANTE_INSCRITO) && 
                     (p.Participante.nombres.Contains(nombres)) &&
                     (p.Participante.apellidos.Contains(apellidos)) &&
                     (p.codigo.Contains(codigo)))
                    .Where(x => (!bTutor) ||
                        ((DateTime.Now.Year - x.Participante.fechaNacimiento.Year +
                         (DateTime.Now < EntityFunctions.AddYears(x.Participante.fechaNacimiento, DateTime.Now.Year - x.Participante.fechaNacimiento.Year) ? -1 : 0)
                         >= Constantes.MAYORIA_EDAD) && bTutor ) )
                    .Where(x => (!bAsigna) ||
                        ((x.AsignacionGrupo.Count == 0) && bAsigna))
                    .Select(p => new
                    {
                        idParticipanteXEvento = p.idParticipanteXEvento,
                        nombres = p.Participante.nombres,
                        apellidos = p.Participante.apellidos,
                        codigo = p.codigo
                    });
                    
                var queryP = query.OrderAndPaging(jtStartIndex, jtPageSize, jtSorting);

                //Ordenar y paginear
                var participantesCount = query.Count();
                var participantes = queryP.ToList();

                return Json(new { Result = "OK", Records = participantes, TotalRecordCount = participantesCount });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error ParticipanteList: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al obtener listado de participantes." });
            }
        }
        #endregion

        #region "ParticipanteXEvento"
        [HttpPost]
        public JsonResult CancelarInscripcion(int idParticipanteXEvento)
        {
            try
            {
                ParticipanteXEvento participante = UoW.participanteXEventoRepository.FindFirst(p => p.idParticipanteXEvento == idParticipanteXEvento);
                participante.estado = Constantes.ESTADOPARTICIPANTE_CANCELADO;
                UoW.participanteXEventoRepository.Edit(participante);
                UoW.Save();
                AgregarBitacora("Cancelación de inscripción (CancelarInscripcion): " + idParticipanteXEvento.ToString());
                return Json(new { Result = "OK", Message = "Se ha cancelado la inscripción del participante: " + participante.codigo, Estado = participante.estado });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error CancelarInscripcion: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al cancelar inscripción." });
            }
        }

        [HttpPost]
        public JsonResult RealizarCheckin(int idParticipanteXEvento)
        {
            try
            {
                ParticipanteXEvento participante = UoW.participanteXEventoRepository.FindFirst(p => p.idParticipanteXEvento == idParticipanteXEvento);
                participante.checkin = true;
                UoW.participanteXEventoRepository.Edit(participante);
                UoW.Save();
                AgregarBitacora("Checkin (RealizarCheckin): " + idParticipanteXEvento.ToString());
                return Json(new { Result = "OK", Message = "Se ha realizado el checkin del participante: " + participante.codigo, Checkin = Constantes.RESPUESTA_POSITIVA });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error RealizarCheckin: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al realizar checkin." });
            }
        }

        [HttpPost]
        public JsonResult GetEstadoParticipanteOptions()
        {
            try
            {
                var estados = UoW.estadoParticipanteRepository.GetAll().Select(
                                e => new { DisplayText = e.nombre, Value = e.idEstadoParticipante });
                return Json(new { Result = "OK", Options = estados });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error GetEstadoParticipanteOptions: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al obtener listado de estados de participante" });
            }
        }

        [HttpPost]
        public JsonResult ParticipanteXEventoList(string nombres, string apellidos, string edad, string sexo, string estadocivil,
                                     string pais, string iglesia, string documentoID, string estado, string codigo,
                                     string tipotransporte, string pagobus, string datosauto, string duenioauto, string contrato,
                                     string recaudacion, string cortesia, string abonomin, string abonomax, string tutor,
                                     string carta, string firmas, string inscrito, string checkin, int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = null)
        {
            try
            {
                //validar los 22 filtros
                int idEvento = int.Parse(ViewBag.Evento);
                if (string.IsNullOrEmpty(jtSorting))
                    jtSorting = "nombres ASC";
                var query = PersonListByFilter(nombres, apellidos, edad, sexo, estadocivil, pais, iglesia, documentoID, estado, codigo,
                                               tipotransporte, pagobus, datosauto, duenioauto, contrato, recaudacion, cortesia,
                                               abonomin, abonomax, tutor, carta, firmas, checkin, idEvento, inscrito)
                             .Select(p => new { pte = p, pteEvento = p.ParticipanteXEvento.FirstOrDefault(i => i.idEvento == idEvento) })
                             .Select(p => new
                             {
                                 idParticipanteXEvento = p.pteEvento.idParticipanteXEvento,
                                 nombres = p.pte.nombres,
                                 apellidos = p.pte.apellidos,
                                 sexo = p.pte.sexo,
                                 idPais = p.pte.idPais,
                                 idIglesia = p.pte.idIglesia,
                                 edad = DateTime.Now.Year - p.pte.fechaNacimiento.Year +
                                         (DateTime.Now < EntityFunctions.AddYears(p.pte.fechaNacimiento, DateTime.Now.Year - p.pte.fechaNacimiento.Year) ? -1 : 0),
                                 codigo = p.pteEvento.codigo,
                                 estado = p.pteEvento.estado,
                                 fechaInscripcion = p.pteEvento.fechaInscripcion,
                                 idParticipante = p.pte.idParticipante,
                                 pteEvento = p.pteEvento,
                                 checkin = p.pteEvento.checkin != null ? (bool)p.pteEvento.checkin ? Constantes.RESPUESTA_POSITIVA : Constantes.RESPUESTA_NEGATIVA : Constantes.RESPUESTA_NEGATIVA,
                                 habitacionge = p.pteEvento.AsignacionGrupo.Count > 0 ? 
                                               SqlFunctions.StringConvert((double)p.pteEvento.AsignacionGrupo.FirstOrDefault().Grupo.idGrupo) : "",
                                 habitacionhotel = p.pteEvento.AsignacionGrupo.Count > 0 ? 
                                               p.pteEvento.AsignacionGrupo.FirstOrDefault().Grupo.NoHabitacion : null,
                                 edificiohotel = p.pteEvento.AsignacionGrupo.Count > 0 ? 
                                               p.pteEvento.AsignacionGrupo.FirstOrDefault().Grupo.Edificio : null
                             });

                //Ordenar por el valor indicado y Paginear
                var queryP = query.OrderAndPaging(jtStartIndex, jtPageSize, jtSorting);
                var personsCount = query.Count();
                var persons = queryP.ToList()
                    .Select(p => new {
                        idParticipanteXEvento = p.idParticipanteXEvento, nombres = p.nombres, apellidos = p.apellidos,
                        sexo = p.sexo, idPais = p.idPais, idIglesia = p.idIglesia, edad = p.edad, codigo = p.codigo,
                        estado = p.estado, fechaInscripcion = p.fechaInscripcion, idParticipante = p.idParticipante,
                        disponibleLOC = p.pteEvento.AbonoTotalLOC,
                        disponibleUSD = p.pteEvento.AbonoTotalUSD, checkin = p.checkin, habitacionge = p.habitacionge, 
                        habitacionhotel = (p.edificiohotel != null ? p.edificiohotel : "")
                                          + "-" + 
                                          (p.habitacionhotel != null ? p.habitacionhotel.ToString() + "" : "")
                    });

                return Json(new { Result = "OK", Records = persons, TotalRecordCount = personsCount });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error ParticipanteXEventoList: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al obtener listado de participantes." });
            }
        }

        public JsonResult TotalIngresos(string nombres, string apellidos, string edad, string sexo, string estadocivil,
                                     string pais, string iglesia, string documentoID, string estado, string codigo,
                                     string tipotransporte, string pagobus, string datosauto, string duenioauto, string contrato,
                                     string recaudacion, string cortesia, string abonomin, string abonomax, string tutor,
                                     string carta, string firmas, string inscrito, string checkin)
        {
            try
            {
                //validar los 22 filtros
                int idEvento = int.Parse(ViewBag.Evento);
                var query = PersonListByFilter(nombres, apellidos, edad, sexo, estadocivil, pais, iglesia, documentoID, estado, codigo,
                                               tipotransporte, pagobus, datosauto, duenioauto, contrato, recaudacion, cortesia,
                                               abonomin, abonomax, tutor, carta, firmas, checkin, idEvento, inscrito)
                            .Select(p => new { participante = p.ParticipanteXEvento.FirstOrDefault(i => i.idEvento == idEvento) })
                            .ToList();
                Evento evento = UoW.eventoRepository.FindFirst(e => e.idEvento == idEvento);
                decimal? cuotaBus = evento.costoBus;

                decimal? totalLOC = query.Sum(m => m.participante.AbonoTotalLOC);
                decimal? totalUSD = query.Sum(m => m.participante.AbonoTotalUSD);
                decimal? totalBUS = query.Where(m => m.participante.ValidarPagoBus).Count() * cuotaBus;
                string sTotalLOC = totalLOC != null ? ((decimal)totalLOC).ToString(Constantes.SPECIFIER_N) : "0.00";
                string sTotalUSD = totalUSD != null ? ((decimal)totalUSD).ToString(Constantes.SPECIFIER_N) : "0.00";
                string sTotalBUS = totalBUS != null ? ((decimal)totalBUS).ToString(Constantes.SPECIFIER_N) : "0.00";

                return Json(new { Result = "OK", TotalLOC = sTotalLOC, TotalUSD = sTotalUSD, TotalBUS = sTotalBUS });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error TotalIngresos: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al obtener listado de participantes." });
            }
        }

        [HttpPost]
        public JsonResult GetParticipanteXEvento(int idParticipante)
        {
            try
            {
                int idEvento = int.Parse(ViewBag.Evento);
                var lp = UoW.participanteXEventoRepository.FindFirst(x => x.Participante.idParticipante == idParticipante
                    && x.idEvento == idEvento);
                if (lp != null)
                {
                    var participante = new
                    {
                        idParticipanteXEvento = lp.idParticipanteXEvento,
                        codigo = lp.codigo,
                        idTipoTransporte = lp.tipoTransporte != null ? lp.tipoTransporte.ToString() : "",
                        marcaAuto = lp.marcaVehiculo != null ? lp.marcaVehiculo : "",
                        placaAuto = lp.placaVehiculo != null ? lp.placaVehiculo : "",
                        colorAuto = lp.colorVehiculo != null ? lp.colorVehiculo : "",
                        duenioAuto = lp.duenioVehiculo != null ? lp.duenioVehiculo : false,
                        codigoTutor = lp.Tutor != null ? lp.Tutor.codigo : "",
                        cartaMenor = lp.cartaTutor != null ? lp.cartaTutor : false,
                        firmaPadre = lp.firmaPadre != null ? lp.firmaPadre : false,
                        firmaMadre = lp.firmaMadre != null ? lp.firmaMadre : false,
                        firmoContrato = lp.contrato,
                        cortesia = lp.cortesia,
                        recaudacion = lp.recaudacionS,
                        observaciones = lp.observaciones != null ? lp.observaciones : "",
                        esAuto = lp.tipoTransporte != null ? lp.tipoTransporte == Constantes.TIPOTRANSPORTE_AUTO : false
                    };
                    return Json(new { Result = "OK", Record = participante });
                }
                else
                {
                    return Json(new { Result = "ERROR", Message = "No se encontró participante." });
                }
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error GetParticipanteXEvento: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al obtener participante." });
            }
        }
        #endregion

        #region "Funciones Adicionales"
        private void CopiarDataParticipante(ParticipanteXEvento participante, ParticipanteXEvento participanteA, bool actualizar)
        {
            if (actualizar) participanteA.tipoTransporte = participante.tipoTransporte;
            if (participante.tipoTransporte != null)
            {
                participanteA.tipoTransporte = participante.tipoTransporte;
                if (participante.tipoTransporte == Constantes.TIPOTRANSPORTE_BUS)
                {
                    participanteA.placaVehiculo = null;
                    participanteA.marcaVehiculo = null;
                    participanteA.colorVehiculo = null;
                    participanteA.duenioVehiculo = null;
                }
                else if (participante.tipoTransporte == Constantes.TIPOTRANSPORTE_AUTO)
                {
                    if (participante.placaVehiculo != null || actualizar) participanteA.placaVehiculo = participante.placaVehiculo;
                    if (participante.marcaVehiculo != null || actualizar) participanteA.marcaVehiculo = participante.marcaVehiculo;
                    if (participante.colorVehiculo != null || actualizar) participanteA.colorVehiculo = participante.colorVehiculo;
                    if (participante.duenioVehiculo != null || actualizar) participanteA.duenioVehiculo = participante.duenioVehiculo;
                }
            }
            participanteA.contrato = participante.contrato;
            participanteA.cortesia = participante.cortesia;
            if (Constantes.EdadParticipante(participanteA.Participante.fechaNacimiento) < Constantes.MAYORIA_EDAD)
            {
                participanteA.cartaTutor = participante.cartaTutor;
                participanteA.firmaMadre = participante.firmaMadre;
                participanteA.firmaPadre = participante.firmaPadre;
            }
            participanteA.observaciones = participante.observaciones;
            if (!actualizar) participanteA.fechaInscripcion = participante.fechaInscripcion;
            if (!actualizar) participanteA.estado = participante.estado;
            if (participante.idTutor != null || actualizar) participanteA.idTutor = participante.idTutor;
        }

        private ParticipanteXEvento ParticipanteEvento(ICollection<ParticipanteXEvento> lParticipantes)
        {
            int idEvento = int.Parse(ViewBag.Evento);
            ParticipanteXEvento participante = lParticipantes.FirstOrDefault(p => p.idEvento == idEvento);
            return participante;
        }

        private IQueryable<Participante> PersonListByFilter(string nombres, string apellidos, string edad, string sexo, string estadocivil,
                                     string pais, string iglesia, string documentoID, string estado, string codigo,
                                     string tipotransporte, string pagobus, string datosauto, string duenioauto, string contrato,
                                     string recaudacion, string cortesia, string abonomin, string abonomax, string tutor,
                                     string carta, string firmas, string checkin, int iEvento, string inscrito)
        {
            var query = from p in UoW.participanteRepository.GetAll()
                        join x in UoW.participanteXEventoRepository.GetAll() on p.idParticipante equals x.idParticipante into ps
                        from x in ps.DefaultIfEmpty()
                        select new { participante = p, pxevento = x };

            //validar datos personales
            if (!string.IsNullOrEmpty(nombres)) 
                query = query.Where(p => p.participante.nombres.Contains(nombres.Trim()));
            if (!string.IsNullOrEmpty(apellidos))
                query = query.Where(p => p.participante.apellidos.Contains(apellidos.Trim()));
            if (!string.IsNullOrEmpty(edad))
            {
                if (edad.Equals("menor"))
                    query = query.Where(p => DateTime.Now.Year - p.participante.fechaNacimiento.Year +
                            (DateTime.Now < EntityFunctions.AddYears(p.participante.fechaNacimiento, DateTime.Now.Year - p.participante.fechaNacimiento.Year) ? -1 : 0)
                             < Constantes.MAYORIA_EDAD);
                else
                    query = query.Where(p => DateTime.Now.Year - p.participante.fechaNacimiento.Year +
                            (DateTime.Now < EntityFunctions.AddYears(p.participante.fechaNacimiento, DateTime.Now.Year - p.participante.fechaNacimiento.Year) ? -1 : 0)
                             >= Constantes.MAYORIA_EDAD);
            }
            if (!string.IsNullOrEmpty(sexo))
                query = query.Where(p => p.participante.sexo == sexo);
            if (!string.IsNullOrEmpty(estadocivil))
            {
                int iEstadoCivil = int.Parse(estadocivil);
                query = query.Where(p => p.participante.estadoCivil == iEstadoCivil);
            }
            if (!string.IsNullOrEmpty(pais))
            {
                int iPais = int.Parse(pais);
                query = query.Where(p => p.participante.idPais == iPais);
            }
            if (!string.IsNullOrEmpty(iglesia))
            {
                int iIglesia = int.Parse(iglesia);
                query = query.Where(p => p.participante.idIglesia == iIglesia);
            }
            if (!string.IsNullOrEmpty(documentoID))
            {
                bool bDocumentoID = bool.Parse(documentoID);
                query = query.Where(p => (p.participante.DocumentoXParticipante.Count > 0) == bDocumentoID);
            }
            //validar datos del evento (ParticipanteXEvento)
            if (!string.IsNullOrEmpty(estado))
            {
                int iEstado = int.Parse(estado);
                if (iEstado == -1)
                    query = query.Where(p => p.pxevento == null);
                else
                    query = query.Where(p => p.pxevento.estado == iEstado);
            }
            else if (!string.IsNullOrEmpty(inscrito))
            {
                bool bInscrito = bool.Parse(inscrito);
                if (bInscrito)
                {
                    query = query.Where(p =>
                        p.pxevento.estado == Constantes.ESTADOPARTICIPANTE_INSCRITO
                        || p.pxevento.estado == Constantes.ESTADOPARTICIPANTE_CANCELADO);
                }
            }
            if (!string.IsNullOrEmpty(checkin))
            {
                bool bCheckin = bool.Parse(checkin);
                query = query.Where(p => p.pxevento.checkin == bCheckin);
            }
            if (!string.IsNullOrEmpty(codigo))
                query = query.Where(p => p.pxevento.codigo.Contains(codigo));
            if (!string.IsNullOrEmpty(tipotransporte))
            {
                int iTipoTransporte = int.Parse(tipotransporte);
                if (iTipoTransporte == -1)
                    query = query.Where(p => p.pxevento.tipoTransporte == null);
                else
                    query = query.Where(p => p.pxevento.tipoTransporte == iTipoTransporte);
            }
            if (!string.IsNullOrEmpty(pagobus))
            {
                bool bPagoBus = bool.Parse(pagobus);
                query = query.Where(p => (p.pxevento.Pago.FirstOrDefault(x =>
                                         (x.Movimiento.idMotivo == Constantes.MOTIVODEPOSITO_BUS)
                                         && (x.estado == Constantes.ESTADOPAGO_AUTORIZADO)) != null) == bPagoBus);
                //query = query.Where(p => ValidarPagoBus(p.ParticipanteXEvento.FirstOrDefault(x => x.idEvento == iEvento)) == bPagoBus);
            }
            if (!string.IsNullOrEmpty(datosauto))
            {
                if (datosauto == "completo")
                    query = query.Where(p => (p.pxevento.marcaVehiculo != null) && (p.pxevento.placaVehiculo != null) && (p.pxevento.colorVehiculo != null));
                else if (datosauto == "falta")
                    query = query.Where(p => ((p.pxevento.marcaVehiculo != null) || (p.pxevento.placaVehiculo != null) || (p.pxevento.colorVehiculo != null)) &&
                                             ((p.pxevento.marcaVehiculo == null) || (p.pxevento.placaVehiculo == null) || (p.pxevento.colorVehiculo == null)));
                else if (datosauto == "ninguno")
                    query = query.Where(p => (p.pxevento.marcaVehiculo == null) && (p.pxevento.placaVehiculo == null) && (p.pxevento.colorVehiculo == null));
            }
            if (!string.IsNullOrEmpty(duenioauto))
            {
                bool bDuenioAuto = bool.Parse(duenioauto);
                query = query.Where(p => p.pxevento.duenioVehiculo == bDuenioAuto);
            }
            if (!string.IsNullOrEmpty(contrato))
            {
                bool bContrato = bool.Parse(contrato);
                query = query.Where(p => p.pxevento.contrato == bContrato);
            }
            if (!string.IsNullOrEmpty(recaudacion))
            {
                bool bRecaudacion = bool.Parse(recaudacion);
                query = query.Where(p => p.pxevento.recaudacionS == bRecaudacion);
            }
            if (!string.IsNullOrEmpty(cortesia))
            {
                bool bCortesia = bool.Parse(cortesia);
                query = query.Where(p => p.pxevento.cortesia == bCortesia);
            }
            if (!string.IsNullOrEmpty(tutor))
            {
                bool bTutor = bool.Parse(tutor);
                query = query.Where(p => (p.pxevento.idTutor != null) == bTutor);
            }
            if (!string.IsNullOrEmpty(carta))
            {
                bool bCarta = bool.Parse(carta);
                query = query.Where(p => p.pxevento.cartaTutor == bCarta);
            }
            if (!string.IsNullOrEmpty(firmas))
            {
                if (firmas.Equals("padre"))
                    query = query.Where(p => p.pxevento.firmaPadre == true);
                else if (firmas.Equals("madre"))
                    query = query.Where(p => p.pxevento.firmaMadre == true);
                else if (firmas.Equals("ambos"))
                    query = query.Where(p => (p.pxevento.firmaPadre == true) && (p.pxevento.firmaMadre == true));
                else if (firmas.Equals("ninguno"))
                    query = query.Where(p => (p.pxevento.firmaPadre == false) && (p.pxevento.firmaMadre == false));
            }
            if (!string.IsNullOrEmpty(abonomin))
            {
                decimal dAbonomin = decimal.Parse(abonomin);
                query = query.Where(p => (
                                    p.pxevento.Pago.Where(
                                        x => ((x.Movimiento.idMotivo == Constantes.MOTIVODEPOSITO_EVENTO) || (x.Movimiento == null))
                                          && (x.estado == Constantes.ESTADOPAGO_AUTORIZADO)
                                          && (x.montoLOC != null)).Sum(x => x.montoLOC) ?? 0 
                                    + p.pxevento.Pago.Where(
                                        x => ((x.Movimiento.idMotivo == Constantes.MOTIVODEPOSITO_EVENTO) || (x.Movimiento == null))
                                          && (x.estado == Constantes.ESTADOPAGO_AUTORIZADO)
                                          && (x.montoUSD != null)).Sum(x => x.montoUSD) ?? 0 * Constantes.TASA_APROX
                                    + p.pxevento.Recaudacion.Where(
                                        x => x.estado == Constantes.ESTADORECAUDACION_INGRESADO).Sum(x => (decimal?)x.monto) ?? 0
                                    ) >= dAbonomin);
                //query = query.Where(p => ValidarAbono(p.ParticipanteXEvento.FirstOrDefault(x => (x.idEvento == iEvento)), abonomin, true));
            }
            if (!string.IsNullOrEmpty(abonomax))
            {
                decimal dAbonomax = decimal.Parse(abonomax);
                query = query.Where(p => (
                                    p.pxevento.Pago.Where(
                                        x => ((x.Movimiento.idMotivo == Constantes.MOTIVODEPOSITO_EVENTO) || (x.Movimiento == null))
                                          && (x.estado == Constantes.ESTADOPAGO_AUTORIZADO)
                                          && (x.montoLOC != null)).Sum(x => x.montoLOC) ?? 0
                                    + p.pxevento.Pago.Where(
                                        x => ((x.Movimiento.idMotivo == Constantes.MOTIVODEPOSITO_EVENTO) || (x.Movimiento == null))
                                          && (x.estado == Constantes.ESTADOPAGO_AUTORIZADO)
                                          && (x.montoUSD != null)).Sum(lp => lp.montoUSD) ?? 0 * Constantes.TASA_APROX
                                    + p.pxevento.Recaudacion.Where(
                                        x => x.estado == Constantes.ESTADOPAGO_AUTORIZADO).Sum(x => (decimal?)x.monto) ?? 0
                                    ) <= dAbonomax);
                //query = query.Where(p => ValidarAbono(p.ParticipanteXEvento.FirstOrDefault(x => (x.idEvento == iEvento)), abonomax, false));
            }

            var queryP = from q in query
                         select q.participante;
            return queryP;
        }
        #endregion
    }

}